<template>
    <div>
        <div style="display: none;">
            <Headers ref="headersRef" />
        </div>
        <div class="content_search">
            <t-space direction="vertical" style="background-color: #fff !important;">
                <t-select size="large" style="width: 150px;background-color: #fff !important;" v-model="value1" :options="options" />
            </t-space>
            <t-input style="width: 800px;" size="large" v-model="searchValue" class="search_input" />
            <t-button @click="send_btn('send')" class="send_btn" style="margin-left: 10px;" size="large">
                    发送 
            </t-button>
            <t-button @click="send_btn('download')" class="send_btn" style="margin-left: 10px;" size="large">
                    发送并下载 
            </t-button>
        </div>
        <div class="main" style="background-color: #fff;">
            <t-tabs :default-value="1" style="background-color: transparent;">
                <t-tab-panel :value="1" label="Params">
                <p style="margin: 20px;">
                    <!-- Params内容区 -->
                    <Params :paramsData="result" @paramsKey="handleKeyUpdate" @paramsValue="handleValueUpdate"></Params>
                </p>
                </t-tab-panel>
                <t-tab-panel :value="2" label="Authorization">
                <p style="margin: 20px">
                    <!-- Authorization内容 -->
                    <Authorization></Authorization>
                </p>
                </t-tab-panel>
                <t-tab-panel :value="3" label="Headers(4)">
                <p style="margin: 20px">
                    <!-- Headers内容区 -->
                    <Headers></Headers>
                </p>
                </t-tab-panel>
                <t-tab-panel :value="4" label="Body">
                <p style="margin: 20px">
                    <!-- Body内容区 -->
                    <Body ref="bodyRef"></Body>
                </p>
                </t-tab-panel>
                <t-tab-panel :value="5" label="Options">
                <p style="margin: 20px">Options内容区</p>
                </t-tab-panel>
            </t-tabs>
        </div>
    </div>
    <t-divider style="margin: 10px 0;"></t-divider>
        <div class="footer" v-show="empty" >
            <t-empty  :title="title"> </t-empty>
        </div>
        <div v-if="response_result">
            <div class="respond_footer" style="position: relative;">
                <div style=" position: absolute;right:100px; top:0px; z-index: 2;">Status:{{ status }} &nbsp&nbsp Duration:{{ duration }}ms</div>
                <t-tabs :default-value="1">
                    <t-tab-panel :value="1" label="Body" style="margin-left: 0px;" >
                        <n-scrollbar style="max-height: 180px;">
                            <div style="height: 180px;margin-left: 15px;">
                                <pre>{{ responseText }}</pre>
                            </div>
                        </n-scrollbar>
                    </t-tab-panel>
                    <t-tab-panel :value="2" label="Headers">
                        <n-scrollbar style="max-height: 180px;">
                            <div>
                                <t-table :data="data" :columns="columns" :row-key="rowKey" />
                            </div>
                        </n-scrollbar>
                    </t-tab-panel>
                </t-tabs>
            </div>
        </div>
</template>

<script lang="ts" setup>
    import qs from 'qs'
    import {ref,nextTick, watch} from 'vue'
    import Body from './Body.vue';
    import Params from './Params.vue';
    import Headers from './Headers.vue';
    import Authorization from './Authorization.vue';
    import axios from 'axios';



    


    //headers的表格
    const columns = [
        {
            colKey: 'key',
            title: 'key',
        },
        {
            colKey: 'value',
            title: 'value',
        }
    ];
    let data = ref<{ key: string; value: any }[]>([]);
    const rowKey = 'property';

    const currentKey=ref('')
    const currentValue=ref('')
    const bodyRef=ref()

    function handleKeyUpdate(key:string){
        currentKey.value=key 
    }
    function handleValueUpdate(value:string){
        currentValue.value=value
    }
    
    
    

    //空状态
    const title=ref('Hit Send to get a response')
    
    const options = [
    { label: 'GET', value: '1' },
    { label: 'POST', value: '2' },
    { label: 'PUT', value: '3' },
    { label: 'PATCH', value: '4' },
    { label: 'DELETE', value: '5' },
    { label: 'OPTIONS', value: '6' },
    { label: 'HEAD', value: '7' },
    ];

    const value1 = ref('1');

    const searchValue=ref('')

    const headersRef = ref()

    const status=ref(0)
    const duration=ref(0)
    const responseText = ref('')

    const empty=ref(true)
    const response_result=ref(false)

    let result=ref<Array<{ key: string; value: string }>>([])

    //input值的监视
    watch(searchValue,()=>{
        if(searchValue.value.includes('?')){
            const value2=searchValue.value.substring(searchValue.value.indexOf('?')+1)
            const value3=value2.split('&')
            result.value=value3.map(item=>{
                const index=item.indexOf('=')
                if(index===-1){
                    return {key:item,value:''}
                }
                else{   
                    return {
                        key:item.slice(0,index),
                        value:item.slice(index+1)
                    }
                }
            })
        }
        else {
            result.value = [] // 没有 ? 时清空
        }
        // console.log('我是result',result);
    })

    

    //表格值的监视
    watch(
        () => [currentKey.value, currentValue.value],
        () => {
            const url = searchValue.value || ''
            const baseUrl = url.split('?')[0] // 去掉原有 query
            let newQuery = ''

            // 只有当 key 不为空时才拼接
            if (currentKey.value) {
            const k = currentKey.value.trim()
            const v = currentValue.value ? currentValue.value.trim() : ''
            newQuery = `?${k}=${v}`
            }

            // 更新 searchValue
            searchValue.value = newQuery ? `${baseUrl}${newQuery}` : baseUrl
        },
        { immediate: false, deep: true }
    )

    let filename:string

    function send_btn(type: 'send' | 'download'){
        //接收body组件传来的tab和数据
        const bodyData = bodyRef.value?.getFormData?.() || {tab: 'none',data:[]}
        
        
        console.log('@@@@@我是bodyData',bodyData);

        //处理url
        const url = searchValue.value.trim().split('?')[0]
        //处理请求方法
        const request_method=options.find(opt=>opt.value===value1.value)?.label
        //如果没输入url
        if (!url) {
            alert('请输入有效的 URL')
        }

        //get请求的参数处理
            const params=result.value.reduce((obj, item) => {
                if (item.key) {
                obj[item.key] = item.value
                }
                return obj
            }, {} as Record<string, string>)  //{}为初始值，ts断言为key为string，value为string的对象
        
        //content-type的值
        let bodyHeader:string
        //body的值
        let body_data:any
        
        //如果是x-www-form-urlencoded
        if(bodyData.tab==='x-www-form-urlencoded'){     
            bodyHeader='application/x-www-form-urlencoded'
            body_data=qs.stringify(     //将数据变为key=value&key=value
                bodyData.data.reduce((obj:any,item:any)=>{     //bodyData.data是个数组
                    obj[item.key]=item.value
                    return obj
                },{}as Record<string,string>)
            )
        }
        // console.log(body_www_data);
        
        //如果是application/json
        if(bodyData.tab==='raw'){
            //接收body组件传来的select和数据
            const bodyFormData=bodyRef.value.getRawData()
            console.log('@@@@@我是bodyFormData',bodyFormData);
            if(bodyFormData.select==='JSON'){
                bodyHeader='application/json'
                try{
                    //将bodyFormData.data转化为json格式
                    body_data=JSON.parse(bodyFormData.data)
                    // console.log('!!!!🌈',body_data);
                }catch{
                    alert('json格式错误')
                    return
                }
            }
            //如果是text/plain
            if(bodyFormData.select==='Text'){
                bodyHeader='text/plain'
                //将bodyFormData.data转化为text格式
                body_data=bodyFormData.data

            }
        }


        //如果是multipart/form-data
        if(bodyData.tab==='form-data'){

            const formData = new FormData()

            bodyData.data.forEach((item:any) => {
            if (item.type === 'Text' || typeof item.value !== 'object') {
                // text，转成字符串
                formData.append(item.key, String(item.value))
            } else if (item.type === 'file' && item.value instanceof File) {
                //file
                formData.append(item.key, item.value)
                console.log(`上传文件: ${item.key} = ${item.value.name}`)
            }
            })
            body_data=formData
            console.log('我是body_data嘿嘿！',body_data);
            console.log('🔍 检查 FormData 内容:')
            for (let [key, value] of body_data.entries()) {
            console.log('Key:', key, 'Value:', value, '类型:', value instanceof File ? 'file' : typeof value)
            }
            
        }



        // console.log('@@@@',url);
        // console.log('!!!!',request_method);
        // console.log('👉 headersRef:', headersRef.value)


        nextTick(async () => {
            const headers = headersRef.value.getHeadersData()
            const start=Date.now()
            // console.log('✅ 成功获取 params:',params);
            console.log('嘿嘿！',bodyHeader ? { ...headers, 'Content-Type': bodyHeader } : headers);
            
            // let responseType:string
            // if(document.querySelector('.send_btn')?.textContent==='发送并下载'){
            //     responseType='blob'
            // }
            // else{
            //     responseType='text'
            // }

            axios({
                url:url,
                method:request_method,
                headers:bodyHeader ? { ...headers, 'Content-Type': bodyHeader } : headers,
                responseType:  type === 'download' ? 'blob' : 'text',
                params:params,
                data:body_data
            }).then(
                async(res)=>{
                    console.log('请求成功',res);
                    //提取文件名
                    const disposition = res.headers['content-disposition']
                    if (disposition) {
                    const match = disposition.match(/filename\*=UTF-8''(.+)/i)
                    if (match && match[1]) {
                        filename = decodeURIComponent(match[1])
                    }
                    }   
                    //点击发送并下载                 
                    if (type === 'download') {
                        console.log('我应该是一个blob对象！！！',res.data);
                        // responseText.value=await res.data.text()
                        responseText.value = '二进制文件！'
                        // console.log('我是filename!!',filename);
                        await saveFile(res.data)
                    }
                    //点击发送 
                    else {
                        responseText.value=res.data
                    }
                    status.value=res.status
                    duration.value = Date.now() - start
                    empty.value=false
                    response_result.value=true
                    
                    // console.log('我是res的headers',Object.entries(res.headers));
                    //Object.entries将对象变为[[key,value],[key,value]]形式
                    //.map(([key,value]))遍历key,value并返回一个新数组
                    //=> { ... } 是代码块（不自动返回），=> ({ ... }) 是返回一个对象，=> [ ... ] 是返回一个数组 
                    data.value = Object.entries(res.headers).map(([key, value]) => ({
                        key,
                        //Array.isArray判断是不是数组，如果是，则将其转变成字符串，且以，为分隔符
                        value: Array.isArray(value) ? value.join(', ') : value
                        })) 
                },
                err=>{
                    console.log('请求失败',err);
                    status.value=err.status
                    duration.value = Date.now() - start
                    responseText.value=err.response.data
                    empty.value=false
                    response_result.value=true
                }
            )
        })
        
    }

//保存文件函数
async function saveFile(blob:Blob){
    // 弹出保存对话框（Electron）
    //ipcRenderer是vue页面(前端)与main.js(主进程)的通信桥梁，他们两个是独立的进程，不能直接调用对方函数。ipcRenderer让前端发送消息给主进程，主进程处理后返回结果
    //invoke是通信方式
    //show-save-dialog是通道，在主进程中注册的
    const result = await window.ipcRenderer.invoke('show-save-dialog', {
      title: '保存文件',
      defaultPath:filename||'default'
    })
    //判断是否退出
    if (result.canceled || !result.filePath){
        console.log('退出了');
        return
    }

    // 将 Blob 转为 ArrayBuffer（二进制）
    const arrayBuffer = await blob.arrayBuffer()

    // 调用主进程保存文件
    await window.ipcRenderer.invoke('save-file', {
      path: result.filePath,
      data: arrayBuffer
    })

    alert(`文件已保存到: ${result.filePath}`)
}




    
</script>

<style scoped>
    .content_search {
        width: 1000px;
        margin: 30px auto;
        display: flex;

    }
    .main {
        background-color: #e8e8e8;
        margin:auto;
        width: 1000px;
    }
     .footer {
        display: flex;
        justify-content: center;
        align-items: center;
        height: 230px;
    }
    :deep(.t-tabs__bar),
    :deep(.t-tabs__nav-scroll) {
        background-color: #fff;
    }
    :deep(.t-table__th-type) {
        border-right: 1px solid #e8e8e8;
    }
    :deep(.t-table--layout-fixed) {
        border: 1px solid #e8e8e8;
    }
    :deep(.dropdown .t-is-readonly) {
        background-color: #096dd9 !important;
        color: #fff !important;
    }
    /* :deep(.send_btn .t-input__inner) {
        color: white !important;
    }
    :deep(.t-select__right-icon) {
        color: white !important;
    }  */
     /* t-fake-arrow  */

</style>